#ifndef IRIDE_ENGINE3D_H_
#define IRIDE_ENGINE3D_H_

#include"../IPixelDrawer.h"
#include "Vector2.h"
#include "Vector3.h"
#include "Matrix4.h"
#include "Types.h"
#include "Color.h"

// #define PROFILE_TRIANGLE_RENDERING

namespace Iride
{
	class Engine3d
	{
		private:
			IPixelDrawer* const mpDrawer;

		public:
			Engine3d(IPixelDrawer* pDrawer);
			virtual ~Engine3d();

			bool mWireFrame;

			int mWinding;

			void BeginRender();

			void Draw(Vector3 pointA, Vector3 pointB, Vector3 pointC, Color colorA, Color colorB, Color colorC);
			void Draw(Vector3 * vertices, Uint* indices, Color* colors, Uint numTriangles);

			void SetFrustum (Real left, Real right, Real bottom, Real top, Real near, Real far);

			//void RasterTriangle(Vector3 pointA, Vector3 pointB, Vector3 pointC, Color colorA, Color colorB, Color colorC);

			void RasterTriangle(Vector4 pointA, Vector4 pointB, Vector4 pointC, Color colorA, Color colorB, Color colorC);

		protected:

			Matrix4 mFrustrum;

		private:

			Uint mWidth;
			Uint mHeight;

			Real* mDepthBuffer;

			int* mBufferX1;
			int* mBufferX2;

			int* mBufferY1;

			Real* mInvZBuf1;
			Real* mInvZBuf2;
			Real* mInvZBufAtt;

			Real* mDepthBuf1;
			Real* mDepthBuf2;
			Real* mDepthBufSl;

			Color* mColorBuf1;
			Color* mColorBuf2;

			Color* mColorBufSl;

			bool (*mTestWinding)(const Vector3 &pointA, const Vector3 &pointB, const Vector3 &pointC);

			bool IsInsideScreen(const Vector4 &vec);

			void LerpAttribute(Real startAtt, Real endAtt, Uint numValues, Real* invZs, Real* out);
			void LerpAttribute(Real startAtt, Real endAtt, Real startZ, Real endZ, Uint numValues, Real* out);

			void LerpColors(Color colorA, Color colorB, int numColors, Real* invZs, Color * pLerpColors);
			void LerpColors(Color colorA, Color colorB, Real startZ, Real endZ, int numColors, Color * pLerpColors);

			void RasterScanLine(Uint x1, Uint x2, Uint y, Real depth1, Real depth2, Color color1, Color color2, Real originalZ1, Real originalZ2);

			void RasterLine(Uint x1, Uint y1, Uint x2, Uint y2, Color color1, Color color2, Real originalZ1, Real originalZ2);
	};
};


#endif
